package com.harmontronics.hanma.paas.paas.service;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.harmontronics.hanma.paas.paas.consts.NumberEnum;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.HmUser;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.HmUserFields;
import com.harmontronics.hanma.paas.paas.domain.organization.entity.valueobject.I18nKeyEnum;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.mapper.HmUserMapper;
import com.harmontronics.hanma.paas.paas.domain.organization.repository.po.HmUserPO;
import com.harmontronics.hanma.paas.paas.domain.organization.service.HmUserService;
import com.harmontronics.hanma.paas.paas.domain.organization.service.IHmUserService;
import com.harmontronics.hanma.paas.paas.exception.ErrorKeyException;
import com.harmontronics.hanma.paas.paas.token.AppUserTokenKit;
import com.harmontronics.hanma.paas.paas.token.UserInfo;
import com.harmontronics.hanma.paas.paas.utils.PasswordUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Service("hmUserAppService")
@DS("#header.App-Unique")
@ConditionalOnProperty(prefix = "mos.oss",name="enabled",havingValue = "false")
public class HmUserAppService extends HmUserService implements IHmUserService{

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private HmUserMapper hmUserMapper;

    @Autowired
    private AppUserTokenKit appUserTokenKit;

    @Override
    public String login(HmUser userLogin) {
        // 根据工号/手机号查询当前信息
        HmUserPO user =
                hmUserMapper.selectOne(
                        new QueryWrapper<HmUserPO>()
                                .eq(HmUserFields.USER_NAME, userLogin.getUsername())
                                .eq(HmUserFields.STATUS, NumberEnum.ONE.getNum())
                                .eq(HmUserFields.DELETED, NumberEnum.ZERO.getNum()));
        if (user == null) {
            throw new ErrorKeyException(I18nKeyEnum.ACCOUNT_OR_PASSWORD_ERROR);
        }
        if (!PasswordUtil.isEqualMd5Password(
                userLogin.getPassword(), user.getSalt(), user.getPassword())
                || user.getStatus().equals(NumberEnum.TWO.getNum())
                || user.getDeleted().equals(NumberEnum.ONE.getNum())) {
            throw new ErrorKeyException(I18nKeyEnum.ACCOUNT_OR_PASSWORD_ERROR);
        }
        return loginWithUser(user);
    }

    public String hidNoLogin(HmUser userLogin) {
        if (userLogin == null || userLogin.getHidNo() == null) {
            throw new ErrorKeyException(I18nKeyEnum.ACCOUNT_OR_PASSWORD_ERROR);
        }
        HmUserPO user =
                hmUserMapper.selectOne(
                        new QueryWrapper<HmUserPO>()
                                .eq(HmUserFields.HID_NO, userLogin.getHidNo())
                                .eq(HmUserFields.DELETED, NumberEnum.ZERO.getNum()));
        if (user == null) {
            throw new ErrorKeyException(I18nKeyEnum.ACCOUNT_OR_PASSWORD_ERROR);
        }
        if (user.getStatus().equals(NumberEnum.TWO.getNum())
                || user.getDeleted().equals(NumberEnum.ONE.getNum())) {
            throw new ErrorKeyException(I18nKeyEnum.ACCOUNT_OR_PASSWORD_ERROR);
        }
        return loginWithUser(user);
    }

    private String loginWithUser(HmUserPO user) {
        String hashKey = appUserTokenKit.getTokenHashKey(user.getId());

        HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();
        Map<String, String> dataMap = hashOperations.entries(hashKey);
        String cipherKey = appUserTokenKit.makeKey(user.getId());
        if (CollectionUtils.isEmpty(dataMap)) {
            Map<String, String> hashData = new HashMap<>();
            hashData.put(UserInfo.HASH_KEY_USER_ID, user.getId().toString());
            hashData.put(UserInfo.HASH_KEY_ADMIN, user.getIsSuperAdmin() == null ? "0" : (user.getIsSuperAdmin() ? "1" : "0"));
            hashData.put(UserInfo.HASH_KEY_USER_NAME, user.getUsername());
            LocalDateTime expiredTime = LocalDateTime.now().plusHours(1);
            long expiredMilli = expiredTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            hashData.put("KEY_" + cipherKey, String.valueOf(expiredMilli));
            hashOperations.putAll(hashKey, hashData);
            stringRedisTemplate.expire(hashKey, 2, TimeUnit.HOURS);
        } else {
            for (Map.Entry<String, String> entry : dataMap.entrySet()) {
                if (entry.getKey().startsWith("KEY_")) {
                    hashOperations.put(hashKey, entry.getKey(), "0");
                }
            }
            LocalDateTime expiredTime = LocalDateTime.now().plusHours(1);
            long expiredMilli = expiredTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            hashOperations.put(hashKey, "KEY_" + cipherKey, String.valueOf(expiredMilli));
        }
        return cipherKey;
    }

    @Override
    public void logout() {
      appUserTokenKit.delete();
    }




}